<template>
  <text class="flow-text">{{ str }}</text>
</template>

<script setup lang="ts">
import { ref, onMounted, watch } from 'vue'

type State = 'loading' | 'running' | 'pause' | '' | 'stop'

const props = defineProps({
  text: {
    required: true
  },
  state: {
    default: ''
  }
})

const emit = defineEmits(['update:state', 'onStop'])

const str = ref('')
let timer = null

watch(
  () => props.text,
  (newText, oldText) => {
    console.log(newText, oldText)
    if (props.state === 'stop') {
      if (timer) {
        clearInterval(timer)
        timer = null
      }
      str.value = newText
      return
    }

    if (newText !== oldText) {
      if (timer) {
        clearInterval(timer)
        timer = null
      }

      str.value = ''
      emit('update:state', 'running')

      timer = setInterval(() => {
        str.value = newText.slice(0, str.value.length + 1)
        if (str.value.length === newText.length) {
          clearInterval(timer)
          timer = null
          emit('onStop')
          emit('update:state', '')
        }
      }, 60)
    }
  },
  { immediate: true }
)

const onPause = () => {
  if (props.state !== 'pause') {
    if (timer) {
      clearInterval(timer)
      timer = null
      emit('update:state', 'pause')
    }
  } else {
    emit('update:state', 'running')
    timer = setInterval(() => {
      str.value = newText.slice(0, str.value.length + 1)
      if (str.value.length === newText.length) {
        clearInterval(timer)
        timer = null
        emit('onStop')
        emit('update:state', '')
      }
    }, 60)
  }
}
</script>

<style lang="scss" scoped>
.flow-text {
  display: inline-block;
  width: 100%;
  text-align: justify;
  word-break: break-all;
}
</style>
